

import java.util.Hashtable;

import tool.StringUtils;
import db.DBListener;
import db.Mp3DBRecord;
import function.ChainMp3;
import function.ChainMp3Impl;
import function.Mp3File;
import function.search.SearchFunction;
import function.stat.LongStore;

public class DBSearchFunction implements SearchFunction, DBListener {

	private Hashtable index = new Hashtable();
	private int mp3Counter = 0;

	public DBSearchFunction(String[] aFilter) {
		super();
		// TODO Implement filter
	}

	public ChainMp3 find(String searchEntry) throws Throwable {
		return (ChainMp3) index.get(searchEntry);
	}

	public int getMp3Number() {
		return mp3Counter;
	}

	public void processRecord(Mp3DBRecord record) {

		String title = record.getTitle();
		mp3Counter++;
		String key = "";
		if (title.length() > 1) {
			key = title.substring(0, 2).toLowerCase();
		} else {
			key = title + " ";
		}
		Mp3File mp3File = record.getMp3File();
			

		if (!index.containsKey(key)) {
			index.put(key, new ChainMp3Impl(mp3File, null, null));
		} else {
			storeMp3WithPeers(mp3File, key);
		}

		// Treatment of special characters
		if (StringUtils.containsSpecialCharacters(key)) {

			if (!index.containsKey("11")) {
				index.put("11", new ChainMp3Impl(mp3File, null, null));
			} else {
				storeMp3WithPeers(mp3File, "11");
			}
		}

		// Treatment of "the"

		if (key.toLowerCase().startsWith("the ")) {
			String replacingKey = key.substring(4, 6);

			if (!index.containsKey(replacingKey)) {
				index.put(replacingKey, new ChainMp3Impl(mp3File, null, null));
			} else {
				storeMp3WithPeers(mp3File, replacingKey);
			}
		}

	}

	private void storeMp3WithPeers(Mp3File mp3File, String key) {
		ChainMp3 newSibling = null;
		ChainMp3 chainCurrent = (ChainMp3) index.get(key);
		boolean stored = false;

		while (!stored) {
			boolean lowerThanCurrent = (chainCurrent.getMp3File().getFilename()
					.toLowerCase().compareTo(
							mp3File.getFilename().toLowerCase()) >= 0);
			// mp3File < current

			if (lowerThanCurrent) {
				newSibling = new ChainMp3Impl(mp3File, chainCurrent
						.getPrevious(), chainCurrent);
				if (chainCurrent.getPrevious() == null) {
					index.remove(key);
					index.put(key, newSibling);
				} else {
					chainCurrent.getPrevious().setNext(newSibling);
				}
				chainCurrent.setPrevious(newSibling);
				stored = true;
			} else if (chainCurrent.getNext() == null) {
				newSibling = new ChainMp3Impl(mp3File, chainCurrent, null);
				chainCurrent.setNext(newSibling);
				stored = true;
			}
			chainCurrent = chainCurrent.getNext();
		}
	}

	public void readingDone() {
	}
}
